home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland Pascal with Objects 7.0 / PAINT.ZIP / PAINT.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1992-10-27  |  11.6 KB  |  451 lines

  1. {************************************************}
  2. {                                                }
  3. {   ObjectWindows Paint demo                     }
  4. {   Copyright (c) 1992 by Borland International  }
  5. {                                                }
  6. {************************************************}
  7.  
  8. program Paint;
  9.  
  10. { The main program file for the paint program.
  11.  
  12.   The paint program is a simple drawing program that demonstrates the
  13.   use of the Object Windows Library (OWL) and of programming with the Windows
  14.   Graphics Device Interface (GDI).
  15. }
  16.  
  17. uses PaintDef, ResDef, PaintDlg, ToolBar, LineBar, Palette, Canvas,
  18.   WinTypes, WinProcs, OWindows, ODialogs, Strings;
  19.  
  20. {$R PAINT}
  21.  
  22. { Global declarations }
  23. const
  24.  
  25.   FileNameMax = 80;        { Max length of file names }
  26.  
  27. type
  28.  
  29.   {
  30.     The main drawing window. Responsible for creating and maintaining
  31.     subwindows for tool, color and line selection, and for menu management.
  32.   }
  33.   PPaintWin = ^TPaintWin;
  34.   TPaintWin = object(TWindow)
  35.     State: TState;        { Drawing state of the program }
  36.     Palette: PPalette;        { Color palette }
  37.     ToolBar: PToolBar;        { Palette of available tools }
  38.     LineBar: PLineBar;        { Palette of available line widths }
  39.     Canvas: PCanvas;        { Window to actually draw on }
  40.     FileName: array [0..FileNameMax] of Char;
  41.                                 { File name associated with current window }
  42.     CBChainNext: HWnd;        { Next window in the clipboard chain }
  43.  
  44.     { Creation }
  45.     constructor Init;
  46.     function GetClassName: PChar; virtual;
  47.     procedure GetWindowClass(var WndClass: TWndClass); virtual;
  48.     procedure SetUpWindow; virtual;
  49.     function CanClose: Boolean; virtual;
  50.  
  51.     { Utility }
  52.     procedure SetNames(NewName: PChar);
  53.     procedure UpdateChildren;
  54.  
  55.     { Window manager interface routines }
  56.     procedure WMSize(var Msg: TMessage);
  57.       virtual wm_First + wm_Size;
  58.     procedure WMChangeCBChain(var Msg: TMessage);
  59.       virtual wm_First + wm_ChangeCBChain;
  60.     procedure WMDrawClipBoard(var Msg: TMessage);
  61.       virtual wm_First + wm_DrawClipBoard;
  62.     procedure WMDestroy(var Msg: TMessage);
  63.       virtual wm_First + wm_Destroy;
  64.  
  65.     { Menu routines }
  66.     procedure CMFileNew(var Msg: TMessage);
  67.       virtual cm_First + cm_FileNew;
  68.     procedure CMFileOpen(var Msg: TMessage);
  69.       virtual cm_First + cm_FileOpen;
  70.     procedure CMFileSave(var Msg: TMessage);
  71.       virtual cm_First + cm_FileSave;
  72.     procedure CMFileSaveAs(var Msg: TMessage);
  73.       virtual cm_First + cm_FileSaveAs;
  74.  
  75.     procedure CMEditUndo(var Msg: TMessage);
  76.       virtual cm_First + cm_EditUndo;
  77.     procedure CMEditCut(var Msg: TMessage);
  78.       virtual cm_First + cm_EditCut;
  79.     procedure CMEditCopy(var Msg: TMessage);
  80.       virtual cm_First + cm_EditCopy;
  81.     procedure CMEditPaste(var Msg: TMessage);
  82.       virtual cm_First + cm_EditPaste;
  83.     procedure CMEditDelete(var Msg: TMessage);
  84.       virtual cm_First + cm_EditDelete;
  85.     procedure CMEditClear(var Msg: TMessage);
  86.       virtual cm_First + cm_EditClear;
  87.  
  88.     procedure CMOptionsSize(var Msg: TMessage);
  89.       virtual cm_First + cm_OptionsSize;
  90.  
  91.     procedure CMHelpAbout(var Msg: TMessage);
  92.       virtual cm_First + cm_HelpAbout;
  93.   end;
  94.  
  95.   {
  96.     A paint application.
  97.   }
  98.   TPaintApp = object(TApplication)
  99.     procedure InitMainWindow; virtual;
  100.   end;
  101.  
  102. { TPaintWin }
  103.  
  104. { Create a drawing window, initializing its drawing state and associated
  105.   windows.
  106. }
  107. constructor TPaintWin.Init;
  108. begin
  109.   TWindow.Init(nil, 'Paint');
  110.  
  111.   { Set up the menu bar }
  112.   Attr.Menu := LoadMenu(HInstance, 'PaintMenu');
  113.  
  114.   { Initialize the drawing state }
  115.   with State do
  116.   begin
  117.     PaintTool := nil;
  118.     MemDC := 0;
  119.     IsDirtyBitmap := False;
  120.     SetRectEmpty(Selection);
  121.     SelectionBM := 0;
  122.     PenSize := 3;
  123.     PenColor := $000000;
  124.     BrushColor := $FFFFFF;
  125.     BitmapSize.X := 640;
  126.     BitmapSize.Y := 480;
  127.   end;
  128.  
  129.   { Create the associated windows }
  130.   Palette := New(PPalette, Init(@Self, @State));
  131.   ToolBar := New(PToolBar, Init(@Self, @State));
  132.   LineBar := New(PLineBar, Init(@Self, @State));
  133.   Canvas := New(PCanvas, Init(@Self, @State));
  134.  
  135.   { Set up the file name }
  136.   FileName[0] := #0;
  137.  
  138.   CBChainNext := 0;
  139. end;
  140.  
  141. function TPaintWin.GetClassName: PChar;
  142. begin
  143.   GetClassName := 'TPaintWin';
  144. end;
  145.  
  146. procedure TPaintWin.GetWindowClass(var WndClass: TWndClass);
  147. begin
  148.   TWindow.GetWindowClass(WndClass);
  149.   WndClass.hbrBackground := color_AppWorkspace + 1;
  150.   WndClass.hIcon := LoadIcon(HInstance, 'PaintIcon');
  151. end;
  152.  
  153. procedure TPaintWin.SetupWindow;
  154. begin
  155.   TWindow.SetupWindow;
  156.   if IsClipboardFormatAvailable(cf_Bitmap) then
  157.     EnableMenuItem(Attr.Menu, cm_EditPaste, mf_enabled);
  158.   CBChainNext := SetClipBoardViewer(HWindow);
  159. end;
  160.  
  161. { Set the name of the file associated with the window and display it in the
  162.   title bar.
  163. }
  164. procedure TPaintWin.SetNames(NewName: PChar);
  165. var
  166.   Name: array[0..FileNameMax + 10] of Char;     { Title bar has 'Paint -'
  167.                                                   prepended }
  168. begin
  169.  
  170.   { Create name for title bar }
  171.   StrCopy(Name, 'Paint');
  172.   if StrComp(NewName, '') <> 0 then
  173.   begin
  174.     StrCat(Name, ' - ');
  175.     StrCat(Name, NewName);
  176.   end;
  177.  
  178.   { Set title bar }
  179.   SetCaption(Name);
  180.  
  181.   { Set file name }
  182.   StrCopy(FileName, NewName);
  183. end;
  184.  
  185. procedure TPaintWin.UpdateChildren;
  186. var
  187.   S: Integer;            { Lower coordinates of Palette }
  188.   R: TRect;            { Window client area }
  189. begin
  190.   GetClientRect(HWindow, R);
  191.   S := ((R.bottom - 8) div 17) * 3 + 1;
  192.   MoveWindow(Palette^.HWindow, 4, 4, S, R.bottom - 8, True);
  193.   MoveWindow(ToolBar^.HWindow, S + 8, 4, (Ord(MaxTool) + 1) * 31 + 1,
  194.     32, True);
  195.   MoveWindow(LineBar^.HWindow, S + (Ord(MaxTool) + 1) * 31 + 13, 4,
  196.     LineBarWidth, 32, True);
  197.   Canvas^.MoveSelf(S + 8, 40, R.Right - S - 12, R.Bottom - 44, True);
  198. end;
  199.  
  200. { Window manager interface routines }
  201.  
  202. { Resize the window and resize associated windows proportionately.
  203. }
  204. procedure TPaintWin.WMSize(var Msg: TMessage);
  205. begin
  206.   TWindow.WMSize(Msg);
  207.   UpdateChildren;
  208. end;
  209.  
  210. { Update the clipboard chain link, or pass down the message.
  211. }
  212. procedure TPaintWin.WMChangeCBChain(var Msg: TMessage);
  213. begin
  214.   if Msg.WParam = CBChainNext then
  215.     CBChainNext := Msg.lParamLo
  216.   else
  217.     if CBChainNext <> 0 then
  218.       SendMessage(CBChainNext, Msg.Message, Msg.WParam, Msg.lParam);
  219. end;
  220.  
  221. { Enable/disable menus to reflect a change in the state of the clipboard.
  222. }
  223. procedure TPaintWin.WMDrawClipBoard(var Msg: TMessage);
  224. begin
  225.   if IsClipboardFormatAvailable(cf_Bitmap) then
  226.     EnableMenuItem(Attr.Menu, cm_EditPaste, mf_enabled)
  227.   else
  228.     EnableMenuItem(Attr.Menu, cm_EditPaste, mf_grayed);
  229.   if CBChainNext <> 0 then
  230.     SendMessage(CBChainNext, Msg.Message, 0, 0);
  231. end;
  232.  
  233. { Notify the clipboard chain before dying.
  234. }
  235. procedure TPaintWin.WMDestroy(var Msg: TMessage);
  236. begin
  237.   ChangeClipboardChain(HWindow, CBChainNext);
  238.   TWindow.WMDestroy(Msg);
  239. end;
  240.  
  241.  
  242. { File menu functions }
  243. { Create a new canvas and destroy the old one.
  244. }
  245. procedure TPaintWin.CMFileNew(var Msg: TMessage);
  246. var
  247.   CurA: TWindowAttr;        { Save the current window attributes }
  248. begin
  249.  
  250.   { Make sure the current image is saved if desired. }
  251.   if State.IsDirtyBitmap then
  252.     case AskCancel('Save current image?') of
  253.       id_Yes: CMFileSave(Msg);
  254.       id_Cancel: Exit;
  255.     end;
  256.  
  257.   { Mark the bitmap as unmodified }
  258.   State.IsDirtyBitmap := False;
  259.   CurA := Canvas^.Attr;
  260.  
  261.   { Destroy the old canvas }
  262.   Canvas^.Done;
  263.  
  264.   { Create a new one }
  265.   SetNames('');
  266.   Canvas := PCanvas(Application^.MakeWindow(New(PCanvas, Init(@Self,
  267.     @State))));
  268.  
  269.   { Size the window appropriately }
  270.   UpdateChildren;
  271. end;
  272.  
  273. { Read a bitmap from file into the canvas.
  274. }
  275. procedure TPaintWin.CMFileOpen(var msg: TMessage);
  276. var
  277.   FN: array [0..FileNameMax] of Char;        { The file name }
  278.   Curs: HCursor;
  279. begin
  280.  
  281.   { Make sure the current image is saved if desired }
  282.   if State.IsDirtyBitmap then
  283.     case AskCancel('Save current image?') of
  284.       id_Yes: CMFileSave(msg);
  285.       id_Cancel: Exit;
  286.     end;
  287.  
  288.   { Create a mask for the file dialog }
  289.   StrCopy(FN, '*.bmp');
  290.  
  291.   { Prompt for the file and load the bitmap }
  292.   if FileOpenDialog(FN) then
  293.   begin
  294.     Curs := SetCursor(LoadCursor(0, idc_Wait));
  295.     if (Canvas^.Load(FN) <> 0) then
  296.     begin
  297.       SetNames(FN);
  298.       UpdateChildren;
  299.     end;
  300.     SetCursor(Curs);
  301.   end;
  302. end;
  303.  
  304. { Save the current bitmap to file.
  305. }
  306. procedure TPaintWin.CMFileSave(var msg: TMessage);
  307. var Curs: HCursor;        { The current cursor }
  308. begin
  309.   
  310.   { Make sure there is a file name to be saved to }
  311.   if StrComp(FileName, '') = 0 then
  312.     CMFileSaveAs(msg)
  313.   else
  314.   begin
  315.     { Set the cursor while the file is being written }
  316.     Curs := SetCursor(LoadCursor(0, idc_Wait));
  317.     Canvas^.Store(FileName);
  318.     SetCursor(Curs);
  319.   end;
  320. end;
  321.  
  322. { Prompt for a file name then save the current bitmap to that file.
  323. }
  324. procedure TPaintWin.CMFileSaveAs(var msg: TMessage);
  325. var
  326.   FN: array[0..FileNameMax] of Char;    { The file name }
  327.   Curs: HCursor;                           { The current cursor }
  328. begin
  329.   { Create a mask for the file dialog }
  330.   StrCopy(FN, '*.bmp');
  331.  
  332.   { Prompt for the file name }
  333.   if FileSaveDialog(FN) then
  334.   begin
  335.     { Set the cursor while the file is being written }
  336.     Curs := SetCursor(LoadCursor(0, idc_Wait));
  337.     if Canvas^.Store(FN) <> 0 then SetNames(FN);
  338.     SetCursor(Curs);
  339.   end;
  340. end;
  341.  
  342. { Make sure the bitmap is saved if desired before dying or cancel if desired.
  343. }
  344. function TPaintWin.CanClose: Boolean;
  345. var Msg: TMessage;            { Bogus to pass on }
  346. begin
  347.   CanClose := True;
  348.   if State.IsDirtyBitmap then
  349.     case AskCancel('Save current image?') of
  350.       id_Yes: CMFileSave(Msg);
  351.       id_Cancel: CanClose := False;
  352.     end;
  353. end;
  354.  
  355.  
  356. { Edit menu functions }
  357.  
  358. { Undo the last change to the bitmap.
  359. }
  360. procedure TPaintWin.CMEditUndo(var Msg: TMessage);
  361. begin
  362.   Canvas^.Undo;
  363. end;
  364.  
  365. { Copy the current selection to the clipboard and clear it from the screen.
  366. }
  367. procedure TPaintWin.CMEditCut(var Msg: TMessage);
  368. begin
  369.   Canvas^.Cut;
  370. end;
  371.  
  372. { Copy the current selection to the clipboard.
  373. }
  374. procedure TPaintWin.CMEditCopy(var Msg: TMessage);
  375. begin
  376.   Canvas^.Copy;
  377. end;
  378.  
  379. { Retrieve the contents of the clipboard and make it the current selection.
  380. }
  381. procedure TPaintWin.CMEditPaste(var Msg: TMessage);
  382. begin
  383.   ToolBar^.ToolSelect(SelectTool);
  384.   Canvas^.Paste;
  385. end;
  386.  
  387. { Clear the current selection from the screen.
  388. }
  389. procedure TPaintWin.CMEditDelete(var Msg: TMessage);
  390. begin
  391.   Canvas^.Delete;
  392. end;
  393.  
  394. { Clear the entire drawing area.
  395. }
  396. procedure TPaintWin.CMEditClear(var Msg: TMessage);
  397. begin
  398.   Canvas^.ClearAll;
  399. end;
  400.  
  401. { Options }
  402. procedure TPaintWin.CMOptionsSize(var Msg: TMessage);
  403. var
  404.   SizeBMInfo: TSizeBMInfo;
  405. begin
  406.   with SizeBMInfo, State do
  407.     begin
  408.       Width := BitmapSize.X;
  409.       Height := BitmapSize.Y;
  410.       CurrentBMFlag := id_PadBM;
  411.     end;
  412.   if Application^.ExecDialog(New(PSizeBMDialog, Init(@Self, 'SizeBMDialog',
  413.     @SizeBMInfo))) = id_OK then
  414.   begin
  415.     with State, SizeBMInfo do
  416.     begin
  417.       BitmapSize.X := Width;
  418.       BitmapSize.Y := Height;
  419.     end;
  420.     Canvas^.Resize(SizeBMInfo.CurrentBMFlag);
  421.     WMSize(Msg);
  422.   end;
  423. end;
  424.   
  425.  
  426. { Help }
  427. { Display the 'About Box'.
  428. }
  429. procedure TPaintWin.CMHelpAbout(var Msg: TMessage);
  430. begin
  431.   Application^.ExecDialog(New(PDialog, Init(@Self, 'AboutDialog')));
  432. end;
  433.  
  434. { TPaintApp }
  435.  
  436. { Create the main window for the paint application.
  437. }
  438. procedure TPaintApp.InitMainWindow;
  439. begin
  440.   MainWindow := New(PPaintWin, Init);
  441. end;
  442.  
  443. var
  444.   PaintApp: TPaintApp;
  445.  
  446. begin
  447.   PaintApp.Init('Paint');
  448.   PaintApp.Run;
  449.   PaintApp.Done;
  450. end.
  451.